package com.xcm.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xcm.annotation.Operate;
import com.xcm.constant.SysDepartmentConstants;
import com.xcm.dao.SysDepartmentMapper;
import com.xcm.model.SysDepartment;
import com.xcm.model.SysUser;
import com.xcm.model.vo.SysDepartmentVo;
import com.xcm.page.PageInfo;
import com.xcm.service.SysDepartmentService;
import com.xcm.util.SessionUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 部门服务实现
 *
 * @author 林强
 * @date 2018-04-12 11:15
 */
@Service(value = "sysDepartmentService")
public class SysDepartmentServiceImpl implements SysDepartmentService {
    @Autowired
    private SysDepartmentMapper sysDepartmentMapper;
    @Autowired
    private HttpServletRequest request;

    /**
     * 新增
     *
     * @param sysDepartment
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Operate("添加部门")
    @Override
    public int save(SysDepartment sysDepartment) {
        SysUser currentUser = SessionUtils.getSessionUser(request);
        sysDepartment.setCreateTime(System.currentTimeMillis());
        sysDepartment.setUpdateTime(System.currentTimeMillis());
        if (null != currentUser) {
            sysDepartment.setCreateUserId(currentUser.getUserId());
        }
        sysDepartment.setStatus(SysDepartmentConstants.STATUS_USE);
        sysDepartment.setAble(SysDepartmentConstants.ABLE_USE);
        return sysDepartmentMapper.save(sysDepartment);
    }

    /**
     * 新增并返回
     *
     * @param sysDepartment
     * @return
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Operate("添加部门并返回id")
    @Override
    public SysDepartment saveAndGetId(SysDepartment sysDepartment) {
        SysUser currentUser = SessionUtils.getSessionUser(request);
        sysDepartment.setCreateTime(System.currentTimeMillis());
        sysDepartment.setUpdateTime(System.currentTimeMillis());
        if (null != currentUser) {
            sysDepartment.setCreateUserId(currentUser.getUserId());
        }
        sysDepartment.setStatus(SysDepartmentConstants.STATUS_USE);
        sysDepartment.setAble(SysDepartmentConstants.ABLE_USE);
        int index = sysDepartmentMapper.saveAndGetId(sysDepartment);
        return index > 0 ? sysDepartment : null;
    }

    /**
     * 根据id刪除
     *
     * @param id 删除的数据的id
     * @return 1成功，0失败，-1有关联不能删除
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Operate("删除部门(级联删除)")
    @Override
    public int deleteById(Integer id) {
        int row = 0;
        //找到所有子类，并将自己加入
        HashSet<SysDepartmentVo> children = new HashSet<>();
        findAllDepartmentByParent(children, id);
        if (CollectionUtils.isNotEmpty(children)) {
            Set<Integer> idArr = getIdFromListAuthority(children);
            //批量删除
            row += sysDepartmentMapper.batchDelete(idArr);
        }
        return row;
    }

    /**
     * 更新
     *
     * @param sysDepartment 更新的部门
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Operate("修改部门")
    @Override
    public int update(SysDepartment sysDepartment) {
        SysUser currentUser = SessionUtils.getSessionUser(request);
        sysDepartment.setUpdateTime(System.currentTimeMillis());
        if (null != currentUser) {
            sysDepartment.setUpdateUserId(currentUser.getUserId());
        }
        return sysDepartmentMapper.update(sysDepartment);
    }

    /**
     * 根据id查询
     *
     * @param id 主键
     * @return
     */
    @Override
    public SysDepartmentVo getByIdVo(Integer id) {
        return sysDepartmentMapper.getByIdVo(id);
    }

    /**
     * 根据名称查询
     *
     * @param departmentName 部门名称
     * @return
     */
    @Override
    public SysDepartment getByName(String departmentName) {
        return sysDepartmentMapper.getByName(departmentName);
    }

    /**
     * 判断是否可删除
     *
     * @param departmentId
     * @return 可删除返回true, 反之false
     */
    @Override
    public boolean canDelete(Integer departmentId) {
        int count = sysDepartmentMapper.countByParentId(departmentId);
        return count == 0;
    }

    /**
     * 根据id查询
     *
     * @param id 主键
     * @return
     */
    @Override
    public SysDepartment getById(Integer id) {
        return sysDepartmentMapper.getById(id);
    }

    /**
     * 列表分页
     *
     * @param paramMap 参数
     * @param pageNum  第几页
     * @param pageSize 每页几条
     * @return
     */
    @Override
    public PageInfo<SysDepartmentVo> listPage(Map<String, Object> paramMap, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Page<SysDepartmentVo> page = sysDepartmentMapper.listPage(paramMap);
        return PageInfo.build(page);
    }

    /**
     * 查询集合
     *
     * @param paramMap 参数map
     * @return
     */
    @Override
    public List<SysDepartmentVo> list(Map<String, Object> paramMap) {
        return sysDepartmentMapper.list(paramMap);
    }

    /**
     * 递归获取某个部门id下面的所有子部门(包括自己)
     */
    private void findAllDepartmentByParent(Set<SysDepartmentVo> sysAuthoritySet, Integer pid) {
        SysDepartmentVo parent = sysDepartmentMapper.getByIdVo(pid);
        List<SysDepartmentVo> sysAuthorityList = new ArrayList<>();
        if (null != parent) {
            sysAuthorityList.add(parent);
            sysAuthoritySet.addAll(new ArrayList<>(sysAuthorityList));
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("parentId", pid);
            List<SysDepartmentVo> children = sysDepartmentMapper.list(paramMap);
            if (CollectionUtils.isNotEmpty(children)) {
                for (SysDepartmentVo child : children) {
                    //递归子部门
                    findAllDepartmentByParent(sysAuthoritySet, child.getDepartmentId());
                }
            }
        }
    }

    /**
     * 获取集合中对象的id
     *
     * @param sysDepartmentVoSet
     * @return
     */
    private Set<Integer> getIdFromListAuthority(Set<SysDepartmentVo> sysDepartmentVoSet) {
        Set<Integer> idSet = new HashSet<>();
        if (CollectionUtils.isEmpty(sysDepartmentVoSet)) {
            return idSet;
        }
        for (SysDepartmentVo sysDepartmentVo : sysDepartmentVoSet) {
            idSet.add(sysDepartmentVo.getDepartmentId());
        }
        return idSet;
    }
}
